home *** CD-ROM | disk | FTP | other *** search
- /*
- * AudioPlayback.cpp
- *
- * Copyright (C) Alberto Vigata - January 2000 - ultraflask@yahoo.com
- *
- * This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
- *
- * FlasKMPEG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * FlasKMPEG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- #include <windows.h>
- #include <mmsystem.h>
- #include <malloc.h>
- #include <winbase.h>
-
- #include "AudioPlayback.h"
-
-
- #define BUFFER_COUNT 20
- #define BUFFER_SIZE 4096*2
-
-
- // Global static module variables
- static HWAVEOUT hWaveOut;
- static HANDLE hAudioEv;
- static unsigned char buffers[BUFFER_COUNT][BUFFER_SIZE];
- static WAVEHDR wav_hdr[BUFFER_COUNT];
-
- // Init sound output system
- int AudioPlaybackStart(TAudioPlayback *ap)
- {
- WAVEFORMATEX waveFormat;
- int i;
-
- if(!ap)
- return 0;
- // chunk_size must be a multiple of the audio buffer
- if(ap->chunk_size%BUFFER_SIZE != 0)
- return 0;
-
- waveFormat.wFormatTag = WAVE_FORMAT_PCM;
- waveFormat.nChannels = ap->n_channels;
- waveFormat.nSamplesPerSec = ap->sample_freq;
- waveFormat.wBitsPerSample = 16;
- waveFormat.nBlockAlign = waveFormat.nChannels *
- waveFormat.wBitsPerSample /8;
- waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec *
- waveFormat.nBlockAlign;
- waveFormat.cbSize = 0;
-
-
- // Create an event for signaling finished work with audio blocks
- hAudioEv = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- if( waveOutOpen( &hWaveOut,
- WAVE_MAPPER,
- &waveFormat,
- (DWORD)hAudioEv,
- 0,
- CALLBACK_EVENT)
- != MMSYSERR_NOERROR )
- return 0;
-
- // Prepare audio blocks
- for(i=0; i<BUFFER_COUNT; i++)
- {
- wav_hdr[i].lpData = (LPSTR) buffers[i];
- wav_hdr[i].dwBufferLength = BUFFER_SIZE;
- wav_hdr[i].dwFlags = wav_hdr[i].dwFlags | WHDR_DONE;
- if( waveOutPrepareHeader( hWaveOut, &wav_hdr[i], sizeof(wav_hdr[i]) )
- != MMSYSERR_NOERROR )
- return 0;
- }
-
-
- return 1;
- }
-
- int AudioPlaybackWrite(TAudioPlayback *ap, unsigned char *data)
- {
- int remaining_bytes = ap->chunk_size;
- int i;
-
- while( remaining_bytes )
- {
- // fill those blocks that have been played
- // and put them into the queue
- for(i=0; i<BUFFER_COUNT; i++)
- if( (wav_hdr[i].dwFlags & WHDR_DONE) && remaining_bytes)
- {
- memcpy(buffers[i], &data[ ap->chunk_size - remaining_bytes ], BUFFER_SIZE);
- waveOutWrite( hWaveOut, &wav_hdr[i], sizeof(wav_hdr[i]) );
- remaining_bytes -= BUFFER_SIZE;
- }
- // if there is no more data to write, exit
- if(!remaining_bytes)
- break;
- // wait for finished buffers
- WaitForSingleObject(hAudioEv, INFINITE);
- }
- return 1;
- }
-
- int AudioPlaybackStop(TAudioPlayback *ap)
- {
- int i;
- waveOutReset( hWaveOut );
- waveOutClose( hWaveOut );
- // UnPrepare audio blocks
- for(i=0; i<BUFFER_COUNT; i++)
- {
- waveOutUnprepareHeader( hWaveOut, &wav_hdr[i], sizeof(wav_hdr[i]) );
- }
- return 1;
- }